<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script >
   /*  let o1 = {name:'o1'}
    let o2 = {}
    Object.defineProperty(o1,'name',{
      get(){
        return o1.name
      },
      set(newVal){
        o1.name = newVal
      }
    })
    Object.defineProperty(o2,'name',{
      get(){
        return o1.name
      },
      set(newVal){
        o1.name = newVal
      }
    }) */
    // -------------------模拟实现访问app.data.a
    let app = {
      _data:{a:123}
    }
    let config = {
      get:null,
      set:null
    }
    function Observe(obj){
      let keys = Object.keys(obj)
      for(let i = 0; i <keys.length; i++){
        let innerkeys = Object.keys(obj[keys[i]])
        console.log(innerkeys)
        for(let j = 0; j < innerkeys.length; i++){
          console.log(innerkeys[j])
          proxy(obj,'_data',innerkeys[j])
        }
      }
    }
    // app._data.xxx -> app.xxx    app._prop.xxx -> app.xxx
    function proxy(obj,prop,key){
      config.get = function (){
        return obj[prop][key]
      }
      config.set = function(newVal){
        obj[prop][key] = newVal
      }
      console.log(obj,prop,key)
      Object.defineProperty(obj,key,config)
    }
    Observe(app)
    // 解释 proxy

// vue 设计, 不希望访问 _ 开头的数据
// vue 中有一个潜规则:
//  - _ 开头的数据是私有数据
//  - $ 开头的是只读数据
// app._data.name ->app.name
// 将 对 _data.xxx 的访问 交给了 实例
// 重点: 访问 app 的 xxx 就是在访问 app._data.xxx
/* 0.假设:
var  o1 = { name: '张三' };
// 要有一个对象 o2, 在访问 o2.name 的时候想要访问的是 o1.name
Object.defineProperty( o2, 'name', {
  get() {
    return o1.name
  }
} ); */
/* 1.访问 app 的 xxx 就是在访问 app._data.xxx

Object.defineProperty( app, 'name', {
  get() {
    return app._data.name
  },
  set( newVal ) {
    app._data.name = newVal;
  }
} ) */
/* 2.将属性的操作转换为 参数

function proxy( app, key ) {
  Object.defineProperty( app, key, {
    get() {
      return app._data[ key ]
    },
    set( newVal ) {
      app._data[ key ] = newVal;
    }
  } )
} */
/* 问题3:

在 vue 中不仅仅是只有 data 属性, properties 等等 都会挂载到 Vue 实例上

function proxy( app, prop, key ) {
  Object.defineProperty( app, key, {
    get() {
      return app[ prop ][ key ]
    },
    set( newVal ) {
      app[ prop ][ key ] = newVal;
    }
  } )
}; */

// 如果将 _data 的成员映射到 实例上
/* proxy( 实例, '_data', 属性名 )
// 如果要 _properties 的成员映射到 实例上
proxy( 实例, '_properties', 属性名 ) */
  </script>
</body>
</html>